package com.yuandian.middle.platform.service.impl;

import com.yuandian.api.middle_platform.po.*;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.middle.platform.enums.ResponseSpeedEnum;
import com.yuandian.middle.platform.mapper.AbilityServerMapper;
import com.yuandian.middle.platform.mapper.ApiSdkStatisticsMapper;
import com.yuandian.middle.platform.mapper.InterruptTimeMapper;
import com.yuandian.middle.platform.mapper.ServerDetailMapper;
import com.yuandian.middle.platform.service.IServerDetailService;
import com.yuandian.middle.platform.utils.CommonUtils;
import com.yuandian.po.MergeDataConfig;
import com.yuandian.po.MergeField;
import com.yuandian.utils.MathUtil;
import com.yuandian.utils.MergeDataUtil;
import com.yuandian.utils.PageDataInfo;
import com.yuandian.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigInteger;
import java.util.*;

/**
 * 说明：服务调用详情查询接口实现
 * @Author tianlr
 * @Date 2023/5/23 14:10
 */
@Service
public class ServerDetailServiceImpl implements IServerDetailService {

    @Autowired
    private InterruptTimeMapper interruptTimeMapper;
    @Autowired
    private ServerDetailMapper serverDetailMapper;
    @Autowired
    private AbilityServerMapper abilityServerMapper;
    @Autowired
    private ApiSdkStatisticsMapper apiSdkStatisticsMapper;

    /**
     * 查询中断时长（次数）趋势
     * @param param
     * @return
     */
    @Override
    public R selectDataInterruptTimeTrend(OrgAbilityParam param) {
        //根据能力查询对应的服务
        List<AbilityServerPojo> serverList = abilityServerMapper.selectAbilityServerByAbility(param.getAbilityCode(), param.getServiceCode());
        //频繁访问变量
        int frequentAccess = 2;
        if (serverList != null && serverList.size() > 0) {
            AbilityServerPojo pojo = serverList.get(0);
            frequentAccess = pojo.getIsFrequentAccess();
        }
        //frequentAccess为1，代表示频繁访问
        if (frequentAccess == 1) {
            //查询中断耗时变化趋势
            List<InterruptTimePojo> list = interruptTimeMapper.selectInterruptTimeTrend(param);
            if (list != null && list.size() > 0) {
                long cycleTimeLong = 0, boforeTimeLong = 0;
                String boforeTime = "";
                InterruptTimePojo tmpPojo = null;
                for (InterruptTimePojo pojo : list) {
                    if (pojo.getInterruptIntervalTime() != 1) {
                        for (int i = 1; i < pojo.getInterruptIntervalTime(); i++) {
                            //当前时间戳
                            cycleTimeLong = CommonUtils.stringFormatTimestamp(pojo.getCycleTime(), null);
                            //前1/2/3...分钟的时间戳
                            boforeTime = CommonUtils.dateFormatString(CommonUtils.addMinute(CommonUtils.stringFormatDate(pojo.getCycleTime(), null), -i), null);
                            boforeTimeLong = CommonUtils.stringFormatTimestamp(boforeTime, null);
                            if (boforeTimeLong >= cycleTimeLong) {
                                tmpPojo = new InterruptTimePojo();
                                tmpPojo.setCycleTime(boforeTime);
                                tmpPojo.setInterruptIntervalTime(1);
                                list.add(tmpPojo);
                            }
                        }
                        pojo.setInterruptIntervalTime(1);
                    }
                }
                //排序
                Collections.sort(list, new Comparator<InterruptTimePojo>() {
                    @Override
                    public int compare(InterruptTimePojo o1, InterruptTimePojo o2) {
                        return o1.getCycleTime().compareTo(o2.getCycleTime());
                    }
                });
            }

            // 归并数据
            List<MergeField> mergeFieldList = new ArrayList<>();
            mergeFieldList.add(new MergeField("interruptIntervalTime"));
            Map<String, Object> map = MergeDataUtil.mergeData(new MergeDataConfig.Builder(
                    InterruptTimePojo.class,
                    list,
                    param.getStartTime(),
                    param.getEndTime(),
                    mergeFieldList)
                    .build());
            //如果最后一个点的时间与结束时间相同，则去掉
            CommonUtils.removeLastPoint(map, param.getEndTime());
            return R.ok(map);
        } else {
            //查询API和SDK中断次数趋势数据
            List<ApiSdkStatisticsPojo> list = apiSdkStatisticsMapper.selectInterruptCountTrend(param);
            // 归并数据
            List<MergeField> mergeFieldList = new ArrayList<>();
            mergeFieldList.add(new MergeField("interruptCount"));
            Map<String, Object> map = MergeDataUtil.mergeData(new MergeDataConfig.Builder(
                    ApiSdkStatisticsPojo.class,
                    list,
                    param.getStartTime(),
                    param.getEndTime(),
                    mergeFieldList)
                    .build());
            //如果最后一个点的时间与结束时间相同，则去掉
            CommonUtils.removeLastPoint(map, param.getEndTime());
            return R.ok(map);
        }
    }

    /**
     * 查询访问量最大的服务器TopN
     * @return
     */
    @Override
    public R selectDataRequestCountTopN(OrgAbilityParam param) {
        //查询访问量最大服务器TopN
        List<RequestStatisticsPojo> list = serverDetailMapper.selectRequestCountTopN(param);
        if (list != null && list.size() > 0) {
            String ipStr = "";
            for (RequestStatisticsPojo pojo : list) {
                ipStr = pojo.getResponseIp();
                //如果IP中包含“-”，说明是IPV6
                if (ipStr.indexOf("-") > -1) {
                    pojo.setResponseIp(CommonUtils.intToipv6(new BigInteger(ipStr.replace("-", ""))));
                } else {
                    pojo.setResponseIp(CommonUtils.longToIpString(Long.valueOf(ipStr).longValue()));
                }
            }
        }
        return R.ok(list);
    }

    /**
     * 查询新建会话量最大的服务器TopN
     * @return
     */
    @Override
    public R selectDataNewSessionCountTopN(OrgAbilityParam param) {
        //查询新建会话量最大服务器TopN
        List<RequestStatisticsPojo> list = serverDetailMapper.selectNewSessionCountTopN(param);
        if (list != null && list.size() > 0) {
            String ipStr = "";
            for (RequestStatisticsPojo pojo : list) {
                ipStr = pojo.getResponseIp();
                //如果IP中包含“-”，说明是IPV6
                if (ipStr.indexOf("-") > -1) {
                    pojo.setResponseIp(CommonUtils.intToipv6(new BigInteger(ipStr.replace("-", ""))));
                } else {
                    pojo.setResponseIp(CommonUtils.longToIpString(Long.valueOf(ipStr).longValue()));
                }
            }
        }
        return R.ok(list);
    }

    /**
     * 查询系统返回码统计
     * @param param
     * @return
     */
    @Override
    public R selectDataServerResCodeStatistics(OrgAbilityParam param) {
        //查询系统返回码统计
        List<ServerResCodeStatisticsPojo> list = serverDetailMapper.selectServerResCodeStatistics(param);
        return R.ok(list);
    }

    /**
     * 查询业务返回码统计
     * @param param
     * @return
     */
    @Override
    public R selectDataBusinessResCodeStatistics(OrgAbilityParam param) {
        //查询业务返回码统计
        List<BusinessResCodeStatisticsPojo> list = serverDetailMapper.selectBusinessResCodeStatistics(param);
        return  R.ok(list);
    }

    /**
     * 查询TCP分析数据
     * @param param
     * @return
     */
    @Override
    public R selectDataTcp(OrgAbilityParam param) {
        //查询TCP数据
        List<TcpStatisticsPojo> list = serverDetailMapper.selectTcpData(param);
        // 归并数据
        List<MergeField> mergeFieldList = new ArrayList<>();
        mergeFieldList.add(new MergeField("newSessionCount"));
        mergeFieldList.add(new MergeField("connSetupTm"));
        mergeFieldList.add(new MergeField("avgConnSetupTm", ((map, inx, labelTimeUsecList, scale) -> {
            Double count = map.get("newSessionCountList").get(inx);
            Double connTime = map.get("connSetupTmList").get(inx);
            return MathUtil.divideKeepNoFormat(connTime, count, 2);
        })));
        mergeFieldList.add(new MergeField("clientZeroCount"));
        mergeFieldList.add(new MergeField("serverZeroCount"));
        mergeFieldList.add(new MergeField("clientRetryCount"));
        mergeFieldList.add(new MergeField("serverRetryCount"));
        mergeFieldList.add(new MergeField("clientResetCount"));
        mergeFieldList.add(new MergeField("serverResetCount"));
        Map<String, Object> map = MergeDataUtil.mergeData(new MergeDataConfig.Builder(
                TcpStatisticsPojo.class,
                list,
                param.getStartTime(),
                param.getEndTime(),
                mergeFieldList)
                .build());
        //如果最后一个点的时间与结束时间相同，则去掉
        CommonUtils.removeLastPoint(map, param.getEndTime());
        return R.ok(map);
    }

    /**
     * 查询服务调用详情
     * @param param
     * @return
     */
    @Override
    public R selectDataDetail(OrgAbilityParam param) {
        if (StringUtils.isNotNull(param.getResponseTimeDistribution())) {
            //根据能力查询对应的服务
            List<AbilityServerPojo> serverList = abilityServerMapper.selectAbilityServerByAbility(param.getAbilityCode(), param.getServiceCode());
            AbilityServerPojo pojo = null;
            if (serverList != null && serverList.size() > 0) {
                pojo = serverList.get(0);
            }
            //数据库中，响应时间对应的单位是微秒，配置表中对应的时间是毫秒
            if (pojo != null && ResponseSpeedEnum.FAST.getItemValue().equals(param.getResponseTimeDistribution())) {
                param.setResponseTimeMin(0);
                param.setResponseTimeMax(pojo.getFastResUplimitThreshold() * 1000);
            } else if (pojo != null && ResponseSpeedEnum.NORMAL.getItemValue().equals(param.getResponseTimeDistribution())) {
                param.setResponseTimeMin(pojo.getFastResUplimitThreshold() * 1000);
                param.setResponseTimeMax(pojo.getNormalResUplimitThreshold() * 1000);
            } else if (pojo != null && ResponseSpeedEnum.SLOW.getItemValue().equals(param.getResponseTimeDistribution())) {
                param.setResponseTimeMin(pojo.getNormalResUplimitThreshold() * 1000);
                param.setResponseTimeMax(pojo.getSlowResUplimitThreshold() * 1000);
            } else if (pojo != null && ResponseSpeedEnum.SLOWEST.getItemValue().equals(param.getResponseTimeDistribution())) {
                param.setResponseTimeMin(pojo.getSlowResUplimitThreshold() * 1000);
                param.setResponseTimeMax(pojo.getSlowResUplimitThreshold() * 1000);
            } else if (ResponseSpeedEnum.TIMEOUT.getItemValue().equals(param.getResponseTimeDistribution())) {
                param.setTimeOut(1);
            }
        }
        String ipstr = "";
        //根据响应IP查询
        if (StringUtils.isNotNull(param.getResponseIp())) {
            ipstr = param.getResponseIp();
            //IP中包含“:”，说明是IPv6
            if (ipstr.indexOf(":") > -1) {
                param.setResponseIp("-" + CommonUtils.ipv6ToInt(ipstr).toString());
            } else {
                param.setResponseIp(CommonUtils.ipStringToLong(ipstr) + "");
            }
        }
        //根据新建会话响应IP查询
        if (StringUtils.isNotNull(param.getNewSessionResponseIp())) {
            ipstr = param.getNewSessionResponseIp();
            //IP中包含“:”，说明是IPv6
            if (ipstr.indexOf(":") > -1) {
                param.setNewSessionResponseIp("-" + CommonUtils.ipv6ToInt(ipstr).toString());
            } else {
                param.setNewSessionResponseIp(CommonUtils.ipStringToLong(ipstr) + "");
            }
        }
        //存放查询出来的记录
        List<EffectiveOriWebDataPojo> relist = new ArrayList<>();
        //查询每分钟对应的记录数
        List<Map<String, Object>> listMap = serverDetailMapper.selectRecordMinute(param);
        //记录总条数
        long total = 0;
        if (listMap != null && listMap.size() > 0) {
            //计算符合条件的总数
            for(Map<String, Object> map : listMap) {
                long a = Long.valueOf(String.valueOf(map.get("cnt")));
                total = total + a;
            }
            //记录开始时间
            String startTime = param.getStartTime();
            long startTimeLong = CommonUtils.stringFormatTimestamp(startTime, null);
            //记录结束时间
            String endTime = param.getEndTime();
            long endTimeLong = CommonUtils.stringFormatTimestamp(endTime, null);

            //计算开始位置
            long startIndex = (param.getPageNum() - 1) * param.getPageSize();
            String times = "";
            int num = 0;
            long diff = 0, pageSize = param.getPageSize();
            for (Map<String, Object> map : listMap) {
                diff = pageSize - relist.size();
                if (diff <= 0) {
                    break;
                }
                times = map.get("times").toString();
                if (map.get("cnt") != null) {
                    num = Integer.valueOf(map.get("cnt").toString()).intValue();
                    if (startIndex < num) {
                        //开始时间
                        String st = times + ":00";
                        long stLong = CommonUtils.stringFormatTimestamp(st, null);
                        //结束时间
                        String et = CommonUtils.dateFormatString(CommonUtils.addMinute(CommonUtils.stringFormatDate(st, null), 1), null);
                        long etLong = CommonUtils.stringFormatTimestamp(et, null);
                        if (stLong > startTimeLong) {
                            param.setStartTime(st);
                        } else {
                            param.setStartTime(startTime);
                        }
                        if (etLong < endTimeLong) {
                            param.setEndTime(et);
                        } else {
                            param.setEndTime(endTime);
                        }
                        param.setStartIndex(startIndex);
                        param.setPageSize(diff);
                        //查询服务调用详情数据
                        List<EffectiveOriWebDataPojo> list = serverDetailMapper.selectServerDetail(param);
                        if (list != null && list.size() > 0) {
                            relist.addAll(list);
                            startIndex = 0;
                        }
                    } else {
                        startIndex = startIndex - num;
                    }
                }
            }
        }

        if (relist != null && relist.size() > 0) {
            String reqIpStr = "", resIpStr = "";
            for (EffectiveOriWebDataPojo pojo : relist) {
                reqIpStr = pojo.getRequestIp();
                resIpStr = pojo.getResponseIp();
                //如果IP中包含“-”，说明是IPV6
                if (reqIpStr.indexOf("-") > -1) {
                    pojo.setRequestIp(CommonUtils.intToipv6(new BigInteger(reqIpStr.replace("-", ""))));
                    pojo.setResponseIp(CommonUtils.intToipv6(new BigInteger(resIpStr.replace("-", ""))));
                } else {
                    pojo.setRequestIp(CommonUtils.longToIpString(Long.valueOf(reqIpStr).longValue()));
                    pojo.setResponseIp(CommonUtils.longToIpString(Long.valueOf(resIpStr).longValue()));
                }
            }
        }
        return R.ok(new PageDataInfo(total, relist));
    }
}
